home *** CD-ROM | disk | FTP | other *** search
- /* DensView.m Copyright 1992 Steve Ludtke */
-
- /* This object works by taking passed data and rendering it into an NXImage */
- /* which is then composited to the screen as necessary. When the view is */
- /* resized, the user coordinate system is reset to unit size. Areas can be */
- /* selected by dragging with the mouse. A zoomTo:::: message will be sent to*/
- /* the delegate with the resulting area. */
-
- #import "Plot3DView.h"
- #import "DensView.h"
-
- #import <stdio.h>
- #import <string.h>
- #import <libc.h>
- #import <math.h>
- #import <appkit/NXImage.h>
- #import <appkit/OpenPanel.h>
- #import <appkit/Slider.h>
- #import <dpsclient/psops.h>
- #import <appkit/Application.h>
-
- char hex[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
-
- extern id NXApp;
-
- @implementation DensView
-
- -initFrame:(NXRect *)myrect
- {
- [super initFrame:myrect];
- [self setDrawSize:1.0 :1.0]; /* set size and origin so view is a "unit" */
- [self setDrawOrigin:0.0 :0.0]; /* coordinate system */
- point.y=point.x=0.0; /* origin of image when composited */
- buf=NULL;
- data=NULL;
- image=nil; /* new image is created by -setData::::: */
- return self;
- }
-
- -superviewSizeChanged:(const NXSize *)oldsize
- {
- [super superviewSizeChanged:oldsize];
- [self setDrawSize:1.0 :1.0]; /* fix drawing size */
- [self setData:nx :ny :data :minZ :maxZ]; /* re-render NXImage */
- return self;
- }
-
- /* essentially all this method has to do is composite the NXImage to the */
- /* screen. */
- -drawSelf:(NXRect *)rects :(int)rectCount
- {
-
- if (buf==NULL||data==NULL||image==nil) {
- PSsetgray(NX_BLACK);
- NXRectFill(&bounds);
- return(self);
- }
-
- [image composite:NX_COPY toPoint:&point];
-
- return self;
- }
-
- /* This method receives data and generates the NXImage */
- -setData:(int)Nx :(int)Ny :(float *)Data :(float)MinZ :(float)MaxZ
- {
- NXStream *str;
- static char s[220];
- int i,n,d;
-
- /* Make sure our postscript buffer is big enough */
- if ((Nx*Ny)>bufs) {
- if (buf!=NULL) free(buf);
- buf=malloc(Nx*Ny*2+Nx*Ny/20+400);
- bufs=Nx*Ny;
- }
- data=Data;
- nx=Nx;
- ny=Ny;
- minZ=MinZ;
- maxZ=MaxZ;
-
- /* Since everything conforms properly, it would be quite easy to generate */
- /* an EPS file from this data ... */
- sprintf(s,"%%!PS-Adobe-2.0 EPSF-2.0\n%%%%Origin:0 0\n%%%%BoundingBox: 0 0 %f %f\n%%%%EndComments\n%f %f scale\n/picstr 1 string def\ngsave\n",frame.size.width,frame.size.height,frame.size.width,frame.size.height);
- strcpy(buf,s);
- sprintf(s,"%d %d 8 [%d 0 0 %d 0 0] {currentfile picstr readhexstring pop} image\n",nx,ny,nx,ny);
- strcat(buf,s);
- i=strlen(buf);
- for (n=0; n<(nx*ny); n++) {
- if (n%100==0) buf[i++]='\n';
- d=255*(data[n]-minZ)/(maxZ-minZ);
- if (d>255) d=255;
- if (d<0) d=0;
- buf[i++]=hex[d>>4];
- buf[i++]=hex[d&15];
- }
- buf[i]=0;
- sprintf(s,"\ngrestore\n");
- strcat(buf,s);
-
- /* send the postscript we generated to an NXImage. I know this is a messy */
- /* way of doing things, but it's leftover from a previous incarnation of */
- /* this object and I didn't feel like rewriting it ... */
- str=NXOpenMemory(buf,strlen(buf),NX_READONLY);
- if (image!=nil) [image free];
- image=[NXImage alloc];
- image=[image initFromStream:str];
- NXClose(str);
- /* This is how it used to work */
- /*DPSWritePostScript(DPSGetCurrentContext(), buf, i);*/
-
- [self display];
- return self;
- }
-
- /* Allows the user to select an area of the plot to be passed to the */
- /* delegate via a zoomTo:::: message. */
- -mouseDown:(NXEvent *)oevent
- {
- int oldMask,loop=1;
- NXEvent *event,evs;
- float f,dash[2] = { SS,SS };
-
- evs=*oevent;
- oevent=&evs;
- [self convertPoint:&oevent->location fromView:nil];
-
- oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
-
- while (loop) {
- event = [NXApp getNextEvent:(NX_LMOUSEUPMASK | NX_LMOUSEDRAGGEDMASK)];
- [self convertPoint:&event->location fromView:nil];
-
- switch (event->type) {
- case NX_LMOUSEUP:
- loop = 0;
- if (event->location.x<oevent->location.x) {
- f=event->location.x;
- event->location.x=oevent->location.x;
- oevent->location.x=f;
- }
- if (event->location.y<oevent->location.y) {
- f=event->location.y;
- event->location.y=oevent->location.y;
- oevent->location.y=f;
- }
- if (event->location.x-oevent->location.x<.02) break;
- if (event->location.y-oevent->location.y<.02) break;
- [delegate zoomTo:oevent->location.x :oevent->location.y :event->location.x :event->location.y];
- break;
- case NX_LMOUSEDRAGGED:
- [self lockFocus];
- PSsetlinewidth(0.0);
- [image composite:NX_COPY toPoint:&point];
-
- PSmoveto(oevent->location.x,oevent->location.y);
- PSlineto(event->location.x,oevent->location.y);
- PSlineto(event->location.x,event->location.y);
- PSlineto(oevent->location.x,event->location.y);
- PSlineto(oevent->location.x,oevent->location.y);
-
- PSsetgray(1.0);
- PSsetdash(dash,2,0.0);
- PSgsave();
- PSstroke();
- PSgrestore();
-
- PSsetgray(0.0);
- PSsetdash(dash,2,SS);
- PSstroke();
-
- [self unlockFocus];
- [window flushWindow];
- break;
- }
-
- }
- [window setEventMask:oldMask];
- return self;
- }
-
- -(int)acceptsFirstMouse {
- return (YES);
- }
- @end
-